const LogEnum = {
	OFF: 0,
	TRACE: 1,
	DEBUG: 2,
	INFO: 3,
	WARN: 4,
	ERROR: 5,
	FATAL: 6
};
const LogType = {
	OFF: 'off',
	TRACE: 'trace',
	DEBUG: 'debug',
	INFO: 'info',
	WARN: 'warn',
	ERROR: 'error',
	FATAL: 'fatal'
};

class Logger {
	constructor(level = 1, name = '') {
		this.useLevel = level;
		this.name = name;
		this.levels = {
			trace: {
				levelStyle: 'background:#77787b; color: #fff; border-radius: 3px 0 0 3px;',
				dateStyle: 'background: #1475B2; color: #fff; border-radius: 3px 0 0 3px;',
				methodStyle: 'background: #2F4F4F; color: #fff; border-radius: 3px 0 0 3px;',
				lineStyle: 'background: #FF2D3D; color: #fff; border-radius: 3px 0 0 3px;',
				infoStyle: 'background:#77787b; color: #fff; border-radius: 3px 0 0 3px;',
				level: LogEnum.TRACE,
				name: LogType.TRACE
			},
			debug: {
				levelStyle: 'background: #3c3645;  color: #fff; border-radius: 3px 0 0 3px;',
				dateStyle: 'background: #1475B2; color: #fff; border-radius: 3px 0 0 3px;',
				methodStyle: 'background: #2F4F4F; color: #fff; border-radius: 3px 0 0 3px;',
				lineStyle: 'background: #FF2D3D; color: #fff; border-radius: 3px 0 0 3px;',
				infoStyle: 'background: #3c3645; color: #fff; border-radius: 3px 0 0 3px;',
				level: LogEnum.DEBUG,
				name: LogType.DEBUG
			},
			info: {
				levelStyle: 'background: #005831; color: #fff; border-radius: 3px 0 0 3px;',
				dateStyle: 'background: #1475B2; color: #fff; border-radius: 3px 0 0 3px;',
				methodStyle: 'background: #2F4F4F; color: #fff; border-radius: 3px 0 0 3px;',
				lineStyle: 'background: #FF2D3D; color: #fff; border-radius: 3px 0 0 3px;',
				infoStyle: 'background: #005831; color: #fff; border-radius: 3px 0 0 3px;',
				level: LogEnum.INFO,
				name: LogType.INFO
			},
			warn: {
				levelStyle: 'background: #f58220; color: #fff; border-radius: 3px 0 0 3px;',
				dateStyle: 'background: #1475B2; color: #fff; border-radius: 3px 0 0 3px;',
				methodStyle: 'background: #2F4F4F; color: #fff; border-radius: 3px 0 0 3px;',
				lineStyle: 'background: #FF2D3D; color: #fff; border-radius: 3px 0 0 3px;',
				infoStyle: 'background: #f58220; color: #fff; border-radius: 3px 0 0 3px;',
				level: LogEnum.WARN,
				name: LogType.WARN
			},
			error: {
				levelStyle: 'background: #d71345; color: #fff; border-radius: 3px 0 0 3px;',
				dateStyle: 'background: #1475B2; color: #fff; border-radius: 3px 0 0 3px;',
				methodStyle: 'background: #2F4F4F; color: #fff; border-radius: 3px 0 0 3px;',
				lineStyle: 'background: #FF2D3D; color: #fff; border-radius: 3px 0 0 3px;',
				infoStyle: 'background: #d71345; color: #fff; border-radius: 3px 0 0 3px;',
				level: LogEnum.ERROR,
				name: LogType.ERROR
			},
			fatal: {
				levelStyle: 'background: #a7324a; color: #fff; border-radius: 3px 0 0 3px;',
				dateStyle: 'background: #1475B2; color: #fff; border-radius: 3px 0 0 3px;',
				methodStyle: 'background: #2F4F4F; color: #fff; border-radius: 3px 0 0 3px;',
				lineStyle: 'background: #FF2D3D; color: #fff; border-radius: 3px 0 0 3px;',
				infoStyle: ' color: #a7324a; border-radius: 3px 0 0 3px;',
				level: LogEnum.FATAL,
				name: LogType.FATAL
			},
			off: {
				levelStyle: 'background: #005831; color: #fff; border-radius: 3px 0 0 3px;',
				dateStyle: 'background: #1475B2; color: #fff; border-radius: 3px 0 0 3px;',
				methodStyle: 'background: #2F4F4F; color: #fff; border-radius: 3px 0 0 3px;',
				lineStyle: 'background: #FF2D3D; color: #fff; border-radius: 3px 0 0 3px;',
				infoStyle: 'background: #005831; color: #fff; border-radius: 3px 0 0 3px;',
				level: LogEnum.OFF,
				name: LogType.OFF
			}
		};
	}

	dateFormat(fmt, date) {
		let regs;
		let result = fmt;
		const opt = {
			'y+': date.getFullYear().toString(), // 年
			'M+': (date.getMonth() + 1).toString(), // 月
			'd+': date.getDate().toString(), // 日
			'h+': date.getHours().toString(), // 时
			'm+': date.getMinutes().toString(), // 分
			's+': date.getSeconds().toString(), // 秒
			'S+': String(date.getTime() % 1000) // 毫秒
			// 有其他格式化字符需求可以继续添加，必须转化成字符串
		};
		for (let k in opt) {
			regs = new RegExp('(' + k + ')').exec(fmt);
			if (regs) {
				result = result.replace(regs[1], regs[1].length === 1 ? opt[k] : opt[k].padStart(regs[1].length, '0'));
			}
		}
		return result;
	}
	print(level, msg, ...params) {
		if (this.useLevel === 0 || level.level < this.useLevel) {
			return;
		}

		let fullMsg = '';

		fullMsg += '%c';
		fullMsg += this.dateFormat('yyyy 年 MM 月 dd 日 hh:mm:ss.SSS', new Date());
		fullMsg += '%c';
		fullMsg += '[' + level.name + '] ';
		fullMsg += `%c  [${this.name}]  %c`;
		fullMsg += msg;
		console.info(fullMsg, level.dateStyle, level.levelStyle, level.lineStyle, level.infoStyle, ...params);
	}
	trace(msg, ...params) {
		this.print(this.levels.trace, msg, ...params);
	}
	debug(msg, ...params) {
		this.print(this.levels.debug, msg, ...params);
	}
	info(msg, ...params) {
		this.print(this.levels.info, msg, ...params);
	}
	warn(msg, ...params) {
		this.print(this.levels.warn, msg, ...params);
	}
	error(msg, ...params) {
		this.print(this.levels.error, msg, ...params);
	}
	fatal(msg, ...params) {
		this.print(this.levels.fatal, msg, ...params);
	}
}

export default Logger;
